package com.example.administrator.zkdemo.db.orm;

/**
 * Created with Android Studio.
 * 描述: ${DESCRIPTION}
 * Date: 2018/11/20
 * Time: 11:51
 *
 * @author 晏琦云
 * @version ${VERSION}
 */

import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import com.zkteco.util.YAMLHelper;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public abstract class AbstractORM<K>
        implements LongId, Serializable {
    private static final Map<String, ConnectionSource> sourceMap = new HashMap();

    @DatabaseField(generatedId = true)
    private long ID;
    private Class<K> clazz;
    private Dao<K, Long> dao;

    public AbstractORM(Class<K> paramClass) {
        this.clazz = paramClass;
    }

    public static void addSource(String paramString, ConnectionSource paramConnectionSource)
            throws SQLException {
        sourceMap.put(paramString, paramConnectionSource);
    }

    private Dao<K, Long> getDao()
            throws SQLException {
        ConnectionSource localConnectionSource = (ConnectionSource) sourceMap.get(getDatabaseId());
        if (localConnectionSource == null)
            throw new SQLException("Please make sure you set connectionSource before using ORM features!");
        this.dao = DaoManager.createDao(localConnectionSource, this.clazz);
        return this.dao;
    }

    public K clearTable()
            throws SQLException {
        TableUtils.clearTable(getDao().getConnectionSource(), this.clazz);
        return this;
    }

    public long countOf()
            throws SQLException {
        return getDao().countOf();
    }

    public K create()
            throws SQLException {
        getDao().create(this);
        return this;
    }

    public K createIfNotExists()
            throws SQLException {
        getDao().createIfNotExists(this);
        return this;
    }

    public K createOrUpdate()
            throws SQLException {
        getDao().createOrUpdate(this);
        return this;
    }

    public K createTable()
            throws SQLException {
        TableUtils.createTable(getDao().getConnectionSource(), this.clazz);
        return this;
    }

    public K createTableIfNotExists()
            throws SQLException {
        TableUtils.createTableIfNotExists(getDao().getConnectionSource(), this.clazz);
        return this;
    }

    public void createTableWithDefaults() {
        try {
            createTable();
            Object localObject = getDefaultValues();
            if (localObject != null) {
                localObject = ((List) localObject).iterator();
                while (((Iterator) localObject).hasNext())
                    ((AbstractORM) ((Iterator) localObject).next()).create();
            }
        } catch (Exception localException) {
            localException.printStackTrace();
        }
    }

    public K delete()
            throws SQLException {
        getDao().delete(this);
        return this;
    }

    public K deleteTable()
            throws SQLException {
        TableUtils.dropTable(getDao().getConnectionSource(), this.clazz, true);
        return this;
    }

    public String getDatabaseId() {
        return "";
    }

    public List<AbstractORM<K>> getDefaultValues() {
        try {
            List localList = (List) YAMLHelper.getInstanceFromFile(getYAMLFilePathForDefaultValues());
            return localList;
        } catch (Exception localException) {
            localException.printStackTrace();
        }
        return null;
    }

    public long getID() {
        return this.ID;
    }

    public QueryBuilder<K, Long> getQueryBuilder()
            throws SQLException {
        return getDao().queryBuilder();
    }

    public String getYAMLFilePathForDefaultValues() {
        return "";
    }

    public List<K> queryForAll()
            throws SQLException {
        return getDao().queryForAll();
    }

    public K queryForId(Long paramLong)
            throws SQLException {
        return getDao().queryForId(paramLong);
    }

    public K update()
            throws SQLException {
        getDao().update(this);
        return this;
    }
}
